﻿using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;

namespace Core.Mgr._EventSys
{
    /// <summary>
    /// 事件系统
    /// PS：不能在事件执行过程中，进行该事件的注销操作
    /// </summary>
    public class EventMgr
    {
        private static readonly Dictionary<ushort, List<Action<ITuple>>> _allNotifyActions =
            new();

        /// <summary>
        /// 注册事件
        /// </summary>
        /// <param name="notification"></param>
        /// <param name="action"></param>
        public static void RegHandler(Enum notification, Action<ITuple> action)
        {
            ushort code = (ushort) (notification as ValueType);

            if (!_allNotifyActions.ContainsKey(code))
            {
                var actionList = new List<Action<ITuple>> {action};
                _allNotifyActions.Add(code, actionList);
            }
            else
            {
                //判断List中是否已经注册过相同的Action
                var actionList = _allNotifyActions[code];
                if (actionList.Contains(action))
                {
                    return;
                }

                actionList.Add(action);
            }
        }

        /// <summary>
        /// 注销该通知下所有事件
        /// </summary>
        /// <param name="notification"></param>
        public static void UnRegHandler(Enum notification)
        {
            ushort code = (ushort) (notification as ValueType);
            if (_allNotifyActions.ContainsKey(code))
            {
                _allNotifyActions.Remove(code);
            }
        }

        /// <summary>
        /// 注销该通知下指定事件
        /// </summary>
        /// <param name="notification"></param>
        /// <param name="action"></param>
        public static void UnRegHandler(Enum notification, Action<ITuple> action)
        {
            ushort code = (ushort) (notification as ValueType);
            if (_allNotifyActions.TryGetValue(code, out var handlers))
            {
                for (int i = 0; i < handlers.Count; i++)
                {
                    var handlerWrap = handlers[i];
                    if (handlerWrap != null && handlerWrap == action)
                    {
                        handlers.Remove(handlerWrap);
                        break;
                    }
                }
            }
        }


        /// <summary>
        /// 通知
        /// </summary>
        /// <param name="notification"></param>
        /// <param name="msg"></param>
        public static void Notify(Enum notification, ITuple msg = null)
        {
            ushort code = (ushort) (notification as ValueType);
            if (_allNotifyActions.TryGetValue(code, out var handlers))
            {
                for (int i = 0; i < handlers.Count; i++)
                {
                    handlers[i]?.Invoke(msg);
                }
            }
        }
    }
}